﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GraphicSplit101
{
    public class GraphiSplit
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="grayBytes">图像灰度值的二维数组</param>
        /// <param name="splitCount">切割层数</param>
        /// <param name="imageWidth"></param>
        /// <param name="imageHeight"></param>        
        /// <param name="multiListBlockPosition">下标0代表left，1代表top，2代表切割块的顺序号</param>
        /// <returns></returns>
        public static List<List<byte[,]>> SplitGraphicBytes(byte[,] grayBytes, int splitCount, int imageWidth, int imageHeight, out List<List<int[]>> multiListBlockPosition)
        {
            const int intSplitBlockCount = 2;            
            List<List<byte[,]>> graphicBytesList = new List<List<byte[,]>>();
            int intParentAbsX = 0;
            int intParentAbsY = 0;
            multiListBlockPosition = new List<List<int[]>>();
            for (int i = 0; i < splitCount; i++)
            {
                List<int[]> listBlockPosition = new List<int[]>();
                List<byte[,]> bytesList = new List<byte[,]>();

                if (i == 0)
                {
                    bytesList.AddRange((CrossSplitGraphicBytes(grayBytes, i + 1, out listBlockPosition, 0, 0, imageWidth, imageHeight)));
                }
                else
                {
                    for (int j = 0; j < Math.Pow(intSplitBlockCount, i); j++)
                    {
                        List<int[]> listBlockPositionTemp = new List<int[]>();
                        intParentAbsX = multiListBlockPosition[i - 1][j][0];
                        intParentAbsY = multiListBlockPosition[i - 1][j][1];                        
                        bytesList.AddRange((CrossSplitGraphicBytes(graphicBytesList[i - 1][j], i + 1, out listBlockPositionTemp, intParentAbsX, intParentAbsY, imageWidth, imageHeight)));
                        listBlockPosition.AddRange(listBlockPositionTemp);
                    }
                }
                multiListBlockPosition.Add(listBlockPosition);
                graphicBytesList.Add(bytesList);
            }
            return graphicBytesList;
        }
        private static List<byte[,]> CrossSplitGraphicBytes(byte[,] grayGraphic, int currentLayer, out List<int[]> listBlockPosition, int intParentAbsX, int intParentAbsY, int intImageWidth, int intImageHeight)
        {
            const int intSplitBlockCount = 2;
            //intParity: 1 奇数时横切|0 偶数时纵切
            int intParity = currentLayer % 2;
            int intWidth = grayGraphic.GetLength(0);
            int intHeight = grayGraphic.GetLength(1);
            List<byte[,]> listSplitBlock = new List<byte[,]>();
            listBlockPosition = new List<int[]>();
            if (intParity == 1)
            {
                for (int k = 0; k < intSplitBlockCount; k++)
                {
                    int intNewByteY = 0;
                    int intStartIndex = (intHeight / intSplitBlockCount * k);
                    int intMaxLength = k * intHeight / intSplitBlockCount + intHeight / intSplitBlockCount;
                    byte[,] newByte = new byte[intWidth, (intHeight + 1) / intSplitBlockCount];
                    for (int j = intStartIndex; j < intMaxLength; j++)
                    {
                        for (int i = 0; i < intWidth; i++)
                        {
                            newByte[i, intNewByteY] = grayGraphic[i, j];
                        }
                        intNewByteY += 1;
                    }
                    listSplitBlock.Add(newByte);
                    //newBytePosition 0 left值 1 top值 2 实际Block序号
                    int[] newBytePosition = new int[3];
                    int intBlockSerial = 0;
                    newBytePosition[0] = intParentAbsX;
                    newBytePosition[1] = intParentAbsY + intStartIndex;
                    intBlockSerial = (newBytePosition[1] / intHeight) * (intImageWidth / intWidth) + newBytePosition[0] / intWidth - 1;
                    if (intBlockSerial < 0) intBlockSerial = 0;
                    newBytePosition[2] = intBlockSerial;                  
                    listBlockPosition.Add(newBytePosition);
                }
            }
            else
            {
                for (int k = 0; k < intSplitBlockCount; k++)
                {
                    int intStartIndex = (intWidth / intSplitBlockCount * k);
                    int intMaxLength = k * intWidth / intSplitBlockCount + intWidth / intSplitBlockCount;
                    byte[,] newByte = new byte[(intWidth + 1) / intSplitBlockCount, intHeight];
                    for (int j = 0; j < intHeight; j++)
                    {
                        int intNewByteX = 0;
                        for (int i = intStartIndex; i < intMaxLength; i++)
                        {
                            newByte[intNewByteX, j] = grayGraphic[i, j];                            
                            intNewByteX += 1;
                        }
                    }
                    listSplitBlock.Add(newByte);
                    //newBytePosition 0 left值 1 top值 2 实际Block序号
                    int[] newBytePosition = new int[3];
                    int intBlockSerial = 0;
                    newBytePosition[0] = (intParentAbsX + intStartIndex);
                    newBytePosition[1] = intParentAbsY;
                    intBlockSerial = (newBytePosition[1] / intHeight) * (intImageWidth / intWidth) + newBytePosition[0] / intWidth - 1;
                    if (intBlockSerial < 0) intBlockSerial = 0;
                    listBlockPosition.Add(newBytePosition);
                }
            }
            return listSplitBlock;
        }
    }
}
